// ==============================================================================
// | 包: middleware                                                             |
// | 功能: 认证中间件包                                                         |
// | 说明: 提供JWT认证和管理员权限验证中间件                                     |
// ==============================================================================
package middleware

import (
	"blog_server/common/res"         // 响应处理包
	"blog_server/models/enum"        // 枚举定义包
	"blog_server/service/redis_service/redis_jwt" // Redis JWT黑名单管理服务
	"blog_server/utils/jwts"         // JWT工具包

	"github.com/gin-gonic/gin"      // Gin Web框架
)

// ==============================================================================
// | 函数: AuthMiddleware                                                       |
// | 参数: @c - *gin.Context (Gin上下文)                                          |
// | 功能: JWT认证中间件，验证请求中的令牌是否有效且未被加入黑名单              |
// |----------------------------------------------------------------------------|
// | 流程:                                                                     |
// | 1. 解析请求中的JWT令牌                                                     |
// | 2. 验证令牌是否在黑名单中                                                 |
// | 3. 验证通过则将用户声明信息存储到上下文                                     |
// ==============================================================================
func AuthMiddleware(c *gin.Context) {
	// 步骤1: 从请求中解析JWT令牌
	claims, err := jwts.ParseTokenByGin(c)
	if err != nil {
		// 令牌解析失败，返回错误响应
		res.FailWithError(err, c)
		c.Abort() // 终止请求处理链
		return
	}

	// 步骤2: 检查令牌是否在Redis黑名单中
	blcType, ok := redis_jwt.HasTokenBlackByGin(c)
	if ok {
		// 令牌在黑名单中，返回相应错误信息
		res.FailWithMsg(blcType.Msg(), c)
		c.Abort() // 终止请求处理链
		return
	}

	// 步骤3: 验证通过，将用户声明信息存储到上下文
	c.Set("claims", claims)
	return
}

// ==============================================================================
// | 函数: AdminMiddleware                                                      |
// | 参数: @c - *gin.Context (Gin上下文)                                          |
// | 功能: 管理员权限验证中间件，验证用户是否为管理员且令牌有效                 |
// |----------------------------------------------------------------------------|
// | 流程:                                                                     |
// | 1. 解析请求中的JWT令牌                                                     |
// | 2. 验证用户角色是否为管理员                                                |
// | 3. 验证令牌是否在黑名单中                                                 |
// | 4. 验证通过则将用户声明信息存储到上下文                                     |
// ==============================================================================
func AdminMiddleware(c *gin.Context) {
	// 步骤1: 从请求中解析JWT令牌
	claims, err := jwts.ParseTokenByGin(c)
	if err != nil {
		// 令牌解析失败，返回错误响应
		res.FailWithError(err, c)
		c.Abort() // 终止请求处理链
		return
	}

	// 步骤2: 验证用户角色是否为管理员
	if claims.Role != enum.AdminRole {
		// 角色不是管理员，返回权限错误
		res.FailWithMsg("权限错误", c)
		c.Abort() // 终止请求处理链
		return
	}
	
	// 步骤3: 检查令牌是否在Redis黑名单中
	blcType, ok := redis_jwt.HasTokenBlackByGin(c)
	if ok {
		// 令牌在黑名单中，返回相应错误信息
		res.FailWithMsg(blcType.Msg(), c)
		c.Abort() // 终止请求处理链
		return
	}

	// 步骤4: 验证通过，将用户声明信息存储到上下文
	c.Set("claims", claims)
}
